import httpx
from pathlib import Path
from typing import List, Dict, Optional, Any
import json
import logging

from app.core.config import settings

logger = logging.getLogger(__name__)


class LLMService:
    """大语言模型服务"""

    def __init__(self):
        self.api_key = settings.KIMI_API_KEY
        self.api_base = settings.KIMI_API_BASE
        self.prompts_dir = settings.prompts_path

    async def _make_request(
        self,
        messages: List[Dict[str, str]],
        model: str = "moonshot-v1-8k",
        temperature: float = 0.3,
        max_tokens: Optional[int] = None
    ) -> str:
        """发送API请求"""
        if not self.api_key:
            raise ValueError("KIMI_API_KEY is not configured")

        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }

        data = {
            "model": model,
            "messages": messages,
            "temperature": temperature
        }

        if max_tokens:
            data["max_tokens"] = max_tokens

        try:
            async with httpx.AsyncClient() as client:
                response = await client.post(
                    f"{self.api_base}/chat/completions",
                    headers=headers,
                    json=data,
                    timeout=60.0
                )
                response.raise_for_status()
                result = response.json()
                return result["choices"][0]["message"]["content"]

        except httpx.HTTPError as e:
            logger.error(f"HTTP error in LLM request: {e}")
            raise
        except Exception as e:
            logger.error(f"Error in LLM request: {e}")
            raise

    def load_prompt_template(self, template_name: str) -> str:
        """加载提示词模板"""
        template_path = self.prompts_dir / f"{template_name}.md"
        if not template_path.exists():
            raise FileNotFoundError(f"Template not found: {template_name}")

        with open(template_path, 'r', encoding='utf-8') as f:
            return f.read()

    async def generate_meeting_minutes(
        self,
        transcript: List[Dict[str, Any]],
        template_name: str = "MeetingSecretary",
        custom_prompt: Optional[str] = None,
        meeting_info: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """生成会议纪要"""
        try:
            # 准备转录文本
            transcript_text = "\n".join([
                f"[{item.get('timestamp', 0):.2f}s] {item.get('speaker', 'Unknown')}: {item.get('text', '')}"
                for item in transcript
            ])

            # 获取提示词模板
            if custom_prompt:
                system_prompt = custom_prompt
            else:
                try:
                    template_content = self.load_prompt_template(template_name)
                    # 提取Role部分作为系统提示词
                    system_prompt = template_content.split("# Role:")[1].split("## Profile")[0].strip()
                except FileNotFoundError:
                    # 使用默认提示词
                    system_prompt = """你是一个专业的会议纪要助手，负责根据会议转录文本生成结构化的会议纪要。
                    请提取关键信息，包括主要议题、讨论要点、决定事项和行动计划。"""

            # 构建消息
            messages = [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": f"请根据以下会议转录文本生成会议纪要：\n\n{transcript_text}"}
            ]

            # 添加会议信息
            if meeting_info:
                meeting_info_text = "\n".join([
                    f"会议主题: {meeting_info.get('title', '')}",
                    f"会议时间: {meeting_info.get('meeting_time', '')}",
                    f"参会人员: {', '.join(meeting_info.get('attendees', []))}"
                ])
                messages[-1]["content"] = f"会议信息：\n{meeting_info_text}\n\n{messages[-1]['content']}"

            # 调用LLM
            response = await self._make_request(messages)

            # TODO: 解析LLM响应为结构化数据
            # 这里需要根据具体的响应格式进行解析

            return {
                "content": response,
                "template_used": template_name,
                "model": "moonshot-v1-8k"
            }

        except Exception as e:
            logger.error(f"Error generating meeting minutes: {e}")
            raise

    async def summarize_text(
        self,
        text: str,
        max_length: int = 500,
        language: str = "zh"
    ) -> str:
        """文本摘要"""
        try:
            system_prompt = f"你是一个专业的文本摘要助手。请将以下文本总结为简洁的摘要，最多{max_length}字，使用{language}语言。"

            messages = [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": f"请总结以下文本：\n\n{text}"}
            ]

            response = await self._make_request(messages)
            return response

        except Exception as e:
            logger.error(f"Error summarizing text: {e}")
            raise

    async def extract_key_points(
        self,
        text: str,
        max_points: int = 10
    ) -> List[str]:
        """提取关键要点"""
        try:
            system_prompt = f"你是一个专业的文本分析助手。请从以下文本中提取最多{max_points}个关键要点，每个要点用序号标出。"

            messages = [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": f"请提取以下文本的关键要点：\n\n{text}"}
            ]

            response = await self._make_request(messages)

            # 解析要点
            lines = response.strip().split('\n')
            key_points = []
            for line in lines:
                line = line.strip()
                if line and (line[0].isdigit() or line.startswith('-') or line.startswith('•')):
                    # 移除序号和符号
                    clean_point = line
                    for prefix in ['1.', '2.', '3.', '4.', '5.', '6.', '7.', '8.', '9.', '10.', '-', '•']:
                        if clean_point.startswith(prefix):
                            clean_point = clean_point[len(prefix):].strip()
                            break
                    if clean_point:
                        key_points.append(clean_point)

            return key_points[:max_points]

        except Exception as e:
            logger.error(f"Error extracting key points: {e}")
            raise

    async def generate_action_items(
        self,
        text: str,
        attendees: Optional[List[str]] = None
    ) -> List[Dict[str, Any]]:
        """生成行动项"""
        try:
            attendees_list = ", ".join(attendees) if attendees else "参会人员"

            system_prompt = f"""你是一个专业的会议分析助手。请从以下会议文本中识别和提取行动项。
            对于每个行动项，请提供：任务描述、建议负责人（从以下人员中选择：{attendees_list}）、建议截止时间。
            请以JSON格式返回，格式如下：
            [
                {{"description": "任务描述", "assignee": "负责人", "due_date": "建议截止时间", "priority": "high/medium/low"}}
            ]"""

            messages = [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": f"请从以下会议文本中提取行动项：\n\n{text}"}
            ]

            response = await self._make_request(messages)

            # 尝试解析JSON响应
            try:
                action_items = json.loads(response)
                if isinstance(action_items, list):
                    return action_items
            except json.JSONDecodeError:
                pass

            # 如果JSON解析失败，返回空列表
            logger.warning("Failed to parse action items as JSON")
            return []

        except Exception as e:
            logger.error(f"Error generating action items: {e}")
            raise

    async def health_check(self) -> Dict[str, Any]:
        """健康检查"""
        try:
            # 测试简单的API调用
            test_messages = [
                {"role": "user", "content": "Hello, this is a health check."}
            ]
            response = await self._make_request(test_messages, max_tokens=10)

            return {
                "status": "healthy",
                "api_configured": bool(self.api_key),
                "api_base": self.api_base,
                "test_response_length": len(response)
            }
        except Exception as e:
            return {
                "status": "unhealthy",
                "error": str(e),
                "api_configured": bool(self.api_key)
            }